include(CMakePackageConfigHelpers)
# 构建可执行文件
function(build_exec)
        # 定义要解析的参数类型
        set(options STATIC)                    # 布尔选项（如 VERBOSE, STATIC）
        set(oneValueArgs
            BUILD_TARGET_NAME   # 构建目标名称
            OUT_NAME            # 输出名称
            VERSION             # 版本号
        )                # 单值参数
        set(multiValueArgs
        SOURCES             # 源文件目录
        INCLUDES            # 头文件目录
        LINK           # 链接库
        PACKAGE_DESCRIPTION # 包描述
        PACKAGE_MAINTAINER  # 包维护者
        )  # 多值参数
        # 解析参数
        cmake_parse_arguments(ARGV "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
       # 收集源文件
       file(GLOB_RECURSE SRC
           ${ARGV_SOURCES}/*.cpp
           ${ARGV_SOURCES}/*.c
           ${ARGV_INCLUDES}/*.h
           ${ARGV_INCLUDES}/*.hpp
       )
        # 添加可执行文件
        add_executable(${ARGV_BUILD_TARGET_NAME} ${SRC})

        # 设置目标属性
        set_target_properties(${ARGV_BUILD_TARGET_NAME} PROPERTIES
            # 输出文件名（例如：myapp -> myrunner）
            OUTPUT_NAME ${ARGV_OUT_NAME}
            # 版本信息（可选，某些平台有用）
            VERSION ${ARGV_VERSION}
            SOVERSION 1
            # 包含头文件目录
            INCLUDE_DIRECTORIES ${ARGV_INCLUDES}
            # 编译宏定义
            COMPILE_DEFINITIONS "APP_VERSION=\"${ARGV_VERSION}\";USE_LOGGER"
            # C++ 标准（也可用 target_compile_features）
            CXX_STANDARD 17
            CXX_STANDARD_REQUIRED ON
            CXX_EXTENSIONS OFF
        )
    # 安装目标
    install(TARGETS ${ARGV_BUILD_TARGET_NAME} RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
    # 安装头文件
    # 包含 CPack 模块
    include(InstallRequiredSystemLibraries)
    set(CPACK_PACKAGE_NAME ${ARGV_BUILD_TARGET_NAME})  # 包名称
    set(CPACK_PACKAGE_VERSION ${ARGV_VERSION})  # 包版本
    set(CPACK_PACKAGE_DESCRIPTION ${ARGV_PACKAGE_DESCRIPTION})  # 包描述
    set(CPACK_DEBIAN_PACKAGE_MAINTAINER ${ARGV_PACKAGE_MAINTAINER})  # 设置维护者信息
    set(CPACK_GENERATOR "DEB")  # 指定生成器为 DEB
    set(CPACK_DEBIAN_PACKAGE_SECTION "utils")  # Debian 包所属的软件分类
    set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.14)")  # 依赖项
    #set(CPACK_DEBIAN_PACKAGE_DEPENDS "libmylib-dev")  # 指定依赖的包名
    set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")  # 包优先级
    # 设置默认的安装路径（这对于一些生成器很重要）
    set(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
    include(CPack)
    # ✅ 正确处理 LINK_LIBS
    if(ARGV_LINK)
       foreach(lib IN LISTS ARGV_LINK)
           # 连接库
           target_link_libraries(${ARGV_BUILD_TARGET_NAME} PRIVATE ${lib})
       endforeach()
    endif()
    if(ARGV_STATIC)
        # 控制特定库使用静态链接
        target_link_options(${ARGV_BUILD_TARGET_NAME} PRIVATE -static)
    endif()
endfunction()

# 创建库函数
# 用于创建共享库和静态库
function(create_libs)
    set(options
        SHARED
        STATIC
    )
    set(oneValueArgs
        TARGETS
        OUTPUT
    )
    set(multiValueArgs
        VERSION
        SOURCES
        INCLUDES
        LINK
    )

    cmake_parse_arguments(ARGV
        "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}
    )

    # 检查必要参数
    if(NOT ARGV_TARGETS)
        message(FATAL_ERROR "TARGETS is required.")
    endif()
    if(NOT ARGV_OUTPUT)
        set(ARGV_OUTPUT ${ARGV_TARGETS})
    endif()
    if(NOT ARGV_VERSION)
        set(ARGV_VERSION "1.0.0")
    endif()

    # 收集源文件
    set(SRC "")
    foreach(dir ${ARGV_SOURCES})
        file(GLOB_RECURSE more_src "${dir}/*.cpp")
        list(APPEND SRC ${more_src})
    endforeach()
    foreach(dir ${ARGV_INCLUDES})
        file(GLOB_RECURSE more_hdr "${dir}/*.h" "${dir}/*.hpp")
        list(APPEND SRC ${more_hdr})
    endforeach()

    # 确保有源文件
    if(NOT SRC)
        message(WARNING "No source files found for ${ARGV_TARGETS}.")
    endif()

    # 构建共享库
    if(ARGV_SHARED)
        add_library(${ARGV_TARGETS}-shared SHARED ${SRC})
        target_include_directories(${ARGV_TARGETS}-shared PRIVATE ${ARGV_INCLUDES})
        set_target_properties(${ARGV_TARGETS}-shared PROPERTIES
            VERSION ${ARGV_VERSION}
            SOVERSION ${ARGV_VERSION}
            OUTPUT_NAME ${ARGV_OUTPUT}
            INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${ARGV_INCLUDES}>;$<INSTALL_INTERFACE:include>"
        )
        set_property(TARGET ${ARGV_TARGETS}-shared PROPERTY POSITION_INDEPENDENT_CODE ON)

        install(TARGETS ${ARGV_TARGETS}-shared
            EXPORT ${ARGV_OUTPUT}-shared-Targets
            LIBRARY DESTINATION lib
            ARCHIVE DESTINATION lib
            RUNTIME DESTINATION bin
            INCLUDES DESTINATION include
        )
        install(EXPORT ${ARGV_OUTPUT}-shared-Targets
            NAMESPACE ${ARGV_OUTPUT}::
            DESTINATION lib/cmake/${ARGV_OUTPUT}
            COMPONENT Development
        )
    # ✅ 正确处理 LINK_LIBS
    if(ARGV_LINK)
       foreach(lib IN LISTS ARGV_LINK)
           # 连接库
           target_link_libraries(${ARGV_TARGETS}-shared PRIVATE ${lib})
       endforeach()
    endif()
    endif()

    # 构建静态库
    if(ARGV_STATIC)
        add_library(${ARGV_TARGETS}-static STATIC ${SRC})
        target_include_directories(${ARGV_TARGETS}-static PRIVATE ${ARGV_INCLUDES})
        set_target_properties(${ARGV_TARGETS}-static PROPERTIES
            OUTPUT_NAME ${ARGV_OUTPUT}
            VERSION ${ARGV_VERSION}
            INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${ARGV_INCLUDES}>;$<INSTALL_INTERFACE:include>"
        )

        install(TARGETS ${ARGV_TARGETS}-static
            EXPORT ${ARGV_OUTPUT}-static-Targets
            ARCHIVE DESTINATION lib
            INCLUDES DESTINATION include
        )
        install(EXPORT ${ARGV_OUTPUT}-static-Targets
            NAMESPACE ${ARGV_OUTPUT}::
            DESTINATION lib/cmake/${ARGV_OUTPUT}
            COMPONENT Development
        )
        # ✅ 正确处理 LINK_LIBS
        if(ARGV_LINK)
           foreach(lib IN LISTS ARGV_LINK)
               # 连接库
               target_link_libraries(${ARGV_TARGETS}-static PRIVATE ${lib})
           endforeach()
        endif()
    endif()

    # 安装头文件
    foreach(dir ${ARGV_INCLUDES})
        get_filename_component(include_dir_name "${dir}" NAME)
        install(DIRECTORY "${dir}/"
            DESTINATION include/${include_dir_name}
            COMPONENT Development
            FILES_MATCHING
            PATTERN "*.h"
            PATTERN "*.hpp"
        )
    endforeach()

    # 生成 Config.cmake.in
    set(IN_CONFIG_PATH "${CMAKE_CURRENT_BINARY_DIR}/cmake/${ARGV_OUTPUT}-config.cmake.in")
    file(WRITE "${IN_CONFIG_PATH}"
        "@PACKAGE_INIT@\n"
        "set_and_check(${ARGV_OUTPUT}_INCLUDE_DIR \"\${PACKAGE_PREFIX_DIR}/include\")\n"
        "set_and_check(${ARGV_OUTPUT}_LIBRARY_DIR \"\${PACKAGE_PREFIX_DIR}/lib\")\n"
        "get_filename_component(${ARGV_OUTPUT}_CMAKE_DIR \"\${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
        "check_required_components(${ARGV_OUTPUT})\n"
    )

    # 如果同时构建了 static 和 shared，可以在这里选择加载哪一个
    if(ARGV_SHARED AND ARGV_STATIC)
        file(APPEND "${IN_CONFIG_PATH}"
            "include(\"\${${ARGV_OUTPUT}_CMAKE_DIR}/${ARGV_OUTPUT}-shared-Targets.cmake\")\n"
            "include(\"\${${ARGV_OUTPUT}_CMAKE_DIR}/${ARGV_OUTPUT}-static-Targets.cmake\")\n"
        )
    elseif(ARGV_SHARED)
        file(APPEND "${IN_CONFIG_PATH}"
            "include(\"\${${ARGV_OUTPUT}_CMAKE_DIR}/${ARGV_OUTPUT}-shared-Targets.cmake\")\n"
        )
    elseif(ARGV_STATIC)
        file(APPEND "${IN_CONFIG_PATH}"
            "include(\"\${${ARGV_OUTPUT}_CMAKE_DIR}/${ARGV_OUTPUT}-static-Targets.cmake\")\n"
        )
    endif()

    file(APPEND "${IN_CONFIG_PATH}"
        "include(\"\${CMAKE_CURRENT_LIST_DIR}/${ARGV_OUTPUT}ConfigVersion.cmake\")\n"
    )

    # 生成 Config.cmake
    configure_package_config_file(
        "${IN_CONFIG_PATH}"
        "${CMAKE_CURRENT_BINARY_DIR}/cmake/${ARGV_OUTPUT}Config.cmake"
        INSTALL_DESTINATION lib/cmake/${ARGV_OUTPUT}
        PATH_VARS CMAKE_CURRENT_BINARY_DIR
    )

    # 生成版本文件
    write_basic_package_version_file(
        "${CMAKE_CURRENT_BINARY_DIR}/cmake/${ARGV_OUTPUT}ConfigVersion.cmake"
        VERSION ${ARGV_VERSION}
        COMPATIBILITY SameMajorVersion
    )

    # 安装配置文件
    install(FILES
        "${CMAKE_CURRENT_BINARY_DIR}/cmake/${ARGV_OUTPUT}Config.cmake"
        "${CMAKE_CURRENT_BINARY_DIR}/cmake/${ARGV_OUTPUT}ConfigVersion.cmake"
        DESTINATION lib/cmake/${ARGV_OUTPUT}
        COMPONENT Development
    )
endfunction()